/**
 * 
 */
package gui.controller;

import engine.ExternalSource;
import engine.Service;
import gui.view.EngineMain;
import gui.view.source.SourceRightPanel;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;

import massDistribution.MeasuredAttribute;
import stubs.ServiceStub;

/**
 * @author Elisa Costante
 * 
 */
public class SourceRightListener implements ListSelectionListener,
		ActionListener {

	private SourceRightPanel rightPanel;
	private EngineMain frame;
	private ExternalSource selectedSource;
	private Service selectedService;

	/**
	 * @param rightPanel
	 */
	public SourceRightListener(SourceRightPanel rightPanel, EngineMain frame) {
		this.rightPanel = rightPanel;
		this.frame = frame;
	}

	/**
	 *Shows the attributese measured for the selected service
	 */
	@Override
	public void valueChanged(ListSelectionEvent e) {

		if (e.getValueIsAdjusting())
			;// Ignore extra messages
		else {
			// Row selected change
			ListSelectionModel lsm = (ListSelectionModel) e.getSource();

			int selectedRow = getSelectedRow(lsm);

			if (selectedRow >= 0 && selectedSource != null) {
				// Show the attribute for the selected service
				String selectedServiceName = (String) rightPanel
						.getServicesListTable().getValueAt(selectedRow, 0);
				selectedService = selectedSource
						.getMeasuredService(selectedServiceName);
				if (selectedService == null) {
					rightPanel.setAttributeTableModelList(frame
							.getAttributeArrayList(), false);

				} else if (selectedService.getMeasuredAttributes() != null) {
					rightPanel.setAttributeTableModelList(selectedService
							.getMeasuredAttributes(), true);
				} else if (selectedService.getMeasuredAttributes() == null) {
					rightPanel.setAttributeTableModelList(frame
							.getAttributeArrayList(), false);
				}

			}
		}

	}

	public void actionPerformed(ActionEvent e) {
		if (e.getActionCommand().equalsIgnoreCase("resetServices")) {
			resetServicesAction();
		} else if (e.getActionCommand().equalsIgnoreCase("done")) {
			doneAction();
		} else if (e.getActionCommand().equalsIgnoreCase("resetAttribute")) {
			resetAttributeAction();
		} else if (e.getActionCommand().equalsIgnoreCase("editService")) {
			editService();
		}
	}

	/**
	 * 
	 */
	private void editService() {
		// Show all the monitored attributes for the services or the default if
		// no attribute is set yet.
		selectedService = getSelectedService();
		if (selectedService != null
				&& selectedService.getMeasuredAttributes() != null) {

			rightPanel.setAttributeTableModelList(selectedService
					.getMeasuredAttributes(), true);
		} else {
			rightPanel.setAttributeTableModelList(
					frame.getAttributeArrayList(), false);
		}
		// A questopunto rendere il pannello dei servizio disabilitato
		EngineMain.setEnabledtPanel(rightPanel.getServicePanel(), false);
		EngineMain.setEnabledtPanel(rightPanel.getAttributeForServicePanel(),
				true);

	}

	/**
	 * @return
	 */
	public Service getSelectedService() {
		int selectedRow = rightPanel.getServicesListTable().getSelectedRow();
		if (selectedRow >= 0) {
			String selectedServiceName = (String) rightPanel
					.getServicesTableModel().getValueAt(selectedRow, 0);
			selectedService = new ServiceStub(selectedServiceName);
			return selectedService;
		}
		return null;
	}

	/**
	 * 
	 */
	private void resetServicesAction() {
		// Load of the services defined in to the Services Panel
		rightPanel.setServicesTableModelList(frame.getMonitoredServices(),
				false);
	}

	/**
	 * 
	 */
	private void resetAttributeAction() {
		rightPanel.setAttributeTableModelList(frame.getAttributeArrayList(),
				false);

	}

	/**
	 * 
	 */
	public void doneAction() {
		if (selectedService != null) {

			// Set the measured Attribute to null
			selectedService
					.setMeasuredAttributes(new ArrayList<MeasuredAttribute>());

			// Set the selected attributes to the services
			DefaultTableModel attributeModel = rightPanel
					.getAttributeTableModel();
			int attributeRowCount = attributeModel.getRowCount();
			for (int k = 0; k < attributeRowCount; k++) {
				if ((Boolean) attributeModel.getValueAt(k, 1) == true) {
					String attributeIdentifier = (String) attributeModel
							.getValueAt(k, 0);
					MeasuredAttribute selectedAttribute = frame
							.getAttributeList().get(attributeIdentifier);
					if (!selectedService.getMeasuredAttributes().contains(
							selectedAttribute)) {

						// Add the attribute Measured to the service
						selectedService.addMeasuredAttribute(selectedAttribute);
					}
				}
			}

			ArrayList<Service> serviceOfTheSource = selectedSource
					.getMeasuredServices();
			if (serviceOfTheSource != null) {
				if (!serviceOfTheSource.contains(selectedService)) {
					serviceOfTheSource.add(selectedService);
				} else {
					// the source already contains the service that has to be
					// modified
					serviceOfTheSource.remove(selectedService);
					serviceOfTheSource.add(selectedService);
				}

			} else {
				selectedSource
						.addMeasuredService((ServiceStub) selectedService);
			}

			// Show the new attribute (only the selected)
			rightPanel.setAttributeTableModelList(selectedService
					.getMeasuredAttributes(), true);

			EngineMain.setEnabledtPanel(rightPanel
					.getAttributeForServicePanel(), false);
			EngineMain.setEnabledtPanel(rightPanel.getServicePanel(), true);

		}

	}

	/**
	 * Return the selectedRow or -1 if no row is selected.
	 * 
	 * @param lsm
	 * @return
	 */
	private int getSelectedRow(ListSelectionModel lsm) {
		int selectedRow = -1;
		if (!lsm.isSelectionEmpty()) {
			// Find out which indexes are selected.
			selectedRow = lsm.getMinSelectionIndex();

		}
		return selectedRow;
	}

	/**
	 * Set the <code>selectedSource</code>.
	 * 
	 * @param selectedSource
	 */
	public void setSelectedSource(ExternalSource selectedSource) {
		if (selectedSource != null) {
			this.selectedSource = selectedSource;
			if (selectedSource.getMeasuredServices() != null) {
				// If the source has some services than show the services and
				// for that source, otherwise show all the services
				// unselected.
				rightPanel.setServicesTableModelList(selectedSource
						.getMeasuredServices(), true);

			} else {
				// In this case the source has no services associated
				// So show all the services unselected and all the attribute
				// selected
				ArrayList<Service> servicesFromFrame = frame
						.getMonitoredServices();
				ArrayList<MeasuredAttribute> allAttributes = frame
						.getAttributeArrayList();
				rightPanel.setServicesTableModelList(servicesFromFrame, false);
				rightPanel.setAttributeTableModelList(allAttributes, false);
			}
		}

	}

	public ExternalSource getSelectedSource() {
		return this.selectedSource;
	}
}
